﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;
using TCC_Hotel.Entidades;
using TCC_Hotel.Entidades.Basicas;
using System.Globalization;

namespace TCC_Hotel.Repositorio
{
    public class FuncionarioRepositorio
    {
        ControleBancoDados controle = new ControleBancoDados();

        /// <summary>
        /// Cria o comando SQL e envia para um método inserir um novo funcionario nos bancos de dados
        /// </summary>
        /// <param name="funcionario">Entidade funcionario</param>
        /// <returns>true se inseriu ou false se não</returns>
        public bool CadastrarFuncionario(Funcionario funcionario)
        {
            //Converte o numero decimal de virgula para ponto
            string salario = funcionario.Salario.ToString(CultureInfo.InvariantCulture);

            //definição do comando sql
            string sql = 
                "INSERT INTO Funcionarios VALUES ('" +
                funcionario.Nome + "', '" +
                funcionario.Nascimento.Date + "', '" +
                funcionario.Contato.Telefone[0] + "', '" +
                funcionario.Contato.Telefone[1] + "', '" +
                funcionario.Contato.Celular[0] + "', '" +
                funcionario.Contato.Celular[1] + "', '" +
                funcionario.Contato.Email + "', '" +
                funcionario.Endereco.Logradouro + "', " +
                funcionario.Endereco.Numero + ", '" +
                funcionario.Endereco.Bairro + "', '" +
                funcionario.Endereco.CEP + "', '" +
                funcionario.Endereco.Complemento + "', '" +
                funcionario.Endereco.Cidade + "', '" +
                funcionario.Endereco.Estado.nome + "', '" +
                funcionario.Endereco.Estado.sigla + "', '" +
                funcionario.RG + "', '" +
                funcionario.CPF + "', '" +
                funcionario.PIS + "', '" +
                funcionario.CarteiraTrabalho + "', '" +
                funcionario.Agencia + "', '" +
                funcionario.Banco + "', '" +  
                funcionario.Conta_Corrente + "', '" +
                funcionario.Data_Admissao.Date + "', '" +
                funcionario.Data_Demissao.Date + "', '" +
                funcionario.Cargo + "', '" +
                funcionario.Ativo + "', " +
                salario + ", '" +
                funcionario.Usuario + "', '" +
                funcionario.Senha + "'" + ")";

                //Insere na tabela de permissoes
                sql = sql +
                   " INSERT INTO Permissoes VALUES ('" +
                   funcionario.Usuario + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +
                   false + "', '" +             
                   false + "')";


                //Método que escreve o comando sql nos bancos de dados
                return controle.EscreveBancoDados(sql);
            
        }

        /// <summary>
        /// Recupera no banco todos os funcionarios cadastrados
        /// </summary>
        /// <returns>Lista com todos os funcionarios</returns>
        public List<Funcionario> RecuperarFuncionarios()
        {
            List<Funcionario> listaResposta = new List<Funcionario>();
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Funcionarios";

            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
            SqlCommand comando = new SqlCommand(sql, con);

    //--------tenta conectar no servidor externo-----------------------
            try
            {
              
                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();


                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto funcionarios
                listaResposta = ListarFuncionarios(reader);
              
                //fecha a conexao
                con.Close();

              
            }

     //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {

                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();

                    //le os dados retornados e monta objeto funcionarios
                    listaResposta = ListarFuncionarios(reader);

                    //fecha a conexao
                    con2.Close();

                }
            }
            finally
            {
                con.Close();
            }

            return listaResposta;


        }

        /// <summary>
        /// Recupera um funcionario especifico do banco de dados
        /// </summary>
        /// <param name="CPF">CPF do funcionario que deseja recuperar</param>
        /// <returns>Entidade do funcionario recuperado</returns>
        public Funcionario RecuperarDetalhesFuncionario(string CPF)
        {
            Funcionario resposta = null;
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Funcionarios WHERE CPF = '" + CPF + "'";
           
            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
             SqlCommand comando = new SqlCommand(sql, con);

 //--------tenta conectar no servidor externo-----------------------
            try
            {             

                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();

                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto funcionario
                resposta = ListarFuncionarios(reader).FirstOrDefault();

                //fecha a conexao
                con.Close();


            }
   //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {
                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();
                    //le os dados retornados e monta objeto funcionarios


                    //le os dados retornados e monta objeto funcionario
                    resposta = ListarFuncionarios(reader).FirstOrDefault();
                    

                    //fecha a conexao
                    con2.Close();
                }

            }
            finally
            {
                con.Close();
            }

            return resposta;


        }

        /// <summary>
        /// Recupera um funcionario especifico do banco de dados
        /// </summary>
        /// <param name="CPF">RG do funcionario que deseja recuperar</param>
        /// <returns>Entidade do funcionario recuperado</returns>
        public Funcionario RecuperarDetalhesFuncionarioPorRG(string RG)
        {
            Funcionario resposta = null;
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Funcionarios WHERE RG = '" + RG + "'";

            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
            SqlCommand comando = new SqlCommand(sql, con);

            //--------tenta conectar no servidor externo-----------------------
            try
            {

                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();

                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto funcionario
                resposta = ListarFuncionarios(reader).FirstOrDefault();

                //fecha a conexao
                con.Close();


            }
            //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {
                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();
                    //le os dados retornados e monta objeto funcionarios


                    //le os dados retornados e monta objeto funcionario
                    resposta = ListarFuncionarios(reader).FirstOrDefault();


                    //fecha a conexao
                    con2.Close();
                }

            }
            finally
            {
                con.Close();
            }

            return resposta;


        }

        /// <summary>
        /// Recupera um funcionario especifico do banco de dados
        /// </summary>
        /// <param name="CPF">Usuario do funcionario que deseja recuperar</param>
        /// <returns>Entidade do funcionario recuperado</returns>
        public Funcionario RecuperarDetalhesFuncionarioPorUsuario(string Usuario)
        {
            Funcionario resposta = null;
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Funcionarios WHERE Usuario = '" + Usuario + "'";

            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
            SqlCommand comando = new SqlCommand(sql, con);

            //--------tenta conectar no servidor externo-----------------------
            try
            {

                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();

                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto funcionario
                resposta = ListarFuncionarios(reader).FirstOrDefault();

                //fecha a conexao
                con.Close();


            }
            //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {
                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();
                    //le os dados retornados e monta objeto funcionarios


                    //le os dados retornados e monta objeto funcionario
                    resposta = ListarFuncionarios(reader).FirstOrDefault();


                    //fecha a conexao
                    con2.Close();
                }

            }
            finally
            {
                con.Close();
            }

            return resposta;


        }

        /// <summary>
        /// Recupera um funcionario ativo e especifico do banco de dados
        /// </summary>
        /// <param name="CPF">Usuario do funcionario que deseja recuperar</param>
        /// <returns>Entidade do funcionario recuperado</returns>
        public Funcionario RecuperarDetalhesFuncionarioAtivoPorUsuario(string Usuario)
        {
            Funcionario resposta = null;
            SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoServidor"].ConnectionString);
            SqlDataReader reader;
            //definição do comando sql
            string sql =
                "SELECT * FROM Funcionarios WHERE Usuario = '" + Usuario + "' AND Ativo = 1";

            //Cria uma objeto do tipo comando passando como parametro a string sql e a string de conexão
            SqlCommand comando = new SqlCommand(sql, con);

            //--------tenta conectar no servidor externo-----------------------
            try
            {

                //abre a conexao
                con.Open();

                //Verifica se tem algum comando nao executado no servidor principal
                controle.verificaConsistencia();
                controle.verificaConsistenciaLocal();

                //executa a query
                reader = comando.ExecuteReader();

                //le os dados retornados e monta objeto funcionario
                resposta = ListarFuncionarios(reader).FirstOrDefault();

                //fecha a conexao
                con.Close();


            }
            //--------Ocorreu excessao, conectar no servidor local-------------------------
            catch (SqlException e)
            {
                //erro referente a servidor inacessivel ou timeout ocorreu
                if (e.Number == 53 || e.Number == -2)
                {
                    //configura para apontar no servidor local
                    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["AplicacaoLocal"].ConnectionString);
                    comando.Connection = con2;

                    //abre conexao
                    con2.Open();

                    //executa a query
                    reader = comando.ExecuteReader();
                    //le os dados retornados e monta objeto funcionarios


                    //le os dados retornados e monta objeto funcionario
                    resposta = ListarFuncionarios(reader).FirstOrDefault();


                    //fecha a conexao
                    con2.Close();
                }

            }
            finally
            {
                con.Close();
            }

            return resposta;


        }

        /// <summary>
        /// Edita um funcionario nos bancos de dados
        /// </summary>
        /// <param name="CPF">CPF do funcionario a ser editado</param>
        /// <param name="funcionario">Novas caracteristicas do funcionario</param>
        /// <returns>true se editou ou false se não</returns>
        public bool EditarFuncionario(string CPF, Funcionario funcionario)
        {
            //Converte o numero decimal de virgula para ponto
            string salario = funcionario.Salario.ToString(CultureInfo.InvariantCulture);

            //definição do comando sql
            string sql =
                "UPDATE Funcionarios SET " +
                "Nome = '" + funcionario.Nome + "', " +
                "Nascimento = '" + funcionario.Nascimento.Date + "', " +
                "Telefone1 = '" + funcionario.Contato.Telefone[0] + "', " +
                "Telefone2 = '" + funcionario.Contato.Telefone[1] + "', " +
                "Celular1 = '" + funcionario.Contato.Celular[0] + "', " +
                "Celular2 = '" + funcionario.Contato.Celular[1] + "', " +
                "Email = '" + funcionario.Contato.Email + "', " +
                "Logradouro = '" + funcionario.Endereco.Logradouro + "', " +
                "Numero = " + funcionario.Endereco.Numero + ", " +
                "Bairro = '" + funcionario.Endereco.Bairro + "', " +
                "CEP = '" + funcionario.Endereco.CEP + "', " +
                "Complemento = '" + funcionario.Endereco.Complemento + "', " +
                "Cidade = '" + funcionario.Endereco.Cidade + "', " +
                "Estado = '" + funcionario.Endereco.Estado.nome + "', " +
                "UF = '" + funcionario.Endereco.Estado.sigla + "', " +
                "RG = '" + funcionario.RG + "', " +
                "CPF = '" + funcionario.CPF + "', " +
                "PIS = '" + funcionario.PIS + "', " +
                "Carteira = '" + funcionario.CarteiraTrabalho + "', " +
                "Agencia = '" + funcionario.Agencia + "', " +
                "Banco = '" + funcionario.Banco + "', " +
                "Conta = '" + funcionario.Conta_Corrente + "', " +
                "DataAdmissao = '" + funcionario.Data_Admissao.Date + "', " +
                "DataDemissao = '" + funcionario.Data_Demissao.Date + "', " +
                "Cargo = '" + funcionario.Cargo + "', " +
                "Ativo = '" + funcionario.Ativo + "', " +
                "Salario = " + salario + " WHERE CPF ='" + CPF + "'";

            //Método que escreve o comando sql nos bancos de dados
            return controle.EscreveBancoDados(sql);

        }

        /// <summary>
        /// Troca a senha do funcionario
        /// </summary>
        /// <param name="CPF">Usuario que sera trocado</param>
        /// <param name="funcionario">Nova senha que sera trocada</param>
        /// <returns>true se trocou ou false se não</returns>
        public bool TrocarSenhaFuncionario(string Usuario, string NovaSenha)
        {          

            //definição do comando sql
            string sql =
                "UPDATE Funcionarios SET " +
                "Senha = '" + NovaSenha + "' WHERE Usuario ='" + Usuario + "'";

            //Método que escreve o comando sql nos bancos de dados
            return controle.EscreveBancoDados(sql);

        }

        /// <summary>
        /// Desliga um funcionario do hotel
        /// </summary>
        /// <param name="CPF">CPF do funcionario a ser desligado</param>
        /// <returns>true se desligou ou false se não</returns>
        public bool DesligarFuncionario(string CPF, Funcionario funcionario)
        {
            
            //definição do comando sql
            string sql =
                "UPDATE Funcionarios SET " +
                "DataDemissao = '" + DateTime.Today + "', " +
                "Ativo = '" + false + "' " + "WHERE CPF ='" + CPF + "' ";

            sql = sql + " UPDATE Permissoes SET " +
                "Cadastrar_Compra = '" + false + "', " +
                "Listar_Estoque = '" + false + "', " +
                "Editar_Estoque = '" + false  + "', " +
                "Listar_Apartamento = '" + false + "', " +
                "Cadastrar_Apartamento = '" + false + "', " +
                "Listar_Empresas = '" + false + "', " +
                "Cadastrar_Empresas = '" + false + "', " +
                "Listar_Fornecedores = '" + false + "', " +
                "Cadastrar_Fornecedores = '" + false + "', " +
                "Listar_Funcionarios = '" + false + "', " +
                "Cadastrar_Funcionarios = '" + false + "', " +
                "Desligar_Funcionarios = '" + false + "', " +
                "Listar_Hospedes = '" + false + "', " +
                "Cadastrar_Hospedes = '" + false + "', " +
                "Listar_Produtos = '" + false + "', " +
                "Cadastrar_Produtos = '" + false + "', " +
                "Reservas = '" + false + "', " +
                "Hospedes_Presentes = '" + false + "', " +
                "Hospedes_Antigos = '" + false + "', " +
                "Cadastrar_Vendas = '" + false + "', " +
                "Gerenciar_Permissoes = '" + false + "', " +
                "Gerenciar_Parametros = '" + false + "', " +
                "Gerenciar_Outras = '" + false + "', " +
                "Gerenciar_Receitas = '" + false + "' WHERE Usuario = '" + funcionario.Usuario + "'";



            //Método que escreve o comando sql nos bancos de dados
            return controle.EscreveBancoDados(sql);

        }

        /// <summary>
        /// Lê dados da tabela correspondente através de um comando SQL os montando a lista que é retornada
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public List<Funcionario> ListarFuncionarios(SqlDataReader reader)
        {
            List<Funcionario> listaResposta = new List<Funcionario>();

            //le os dados retornados e monta objeto funcionarios
            while (reader.Read())
            {
                listaResposta.Add(new Funcionario()
                {
                    Nome = Convert.ToString(reader["Nome"]),
                    Nascimento = Convert.ToDateTime(reader["Nascimento"]).Date,
                    Contato = new Contato()
                    {
                        Celular = new List<string>() { Convert.ToString(reader["Celular1"]), Convert.ToString(reader["Celular2"]) },
                        Telefone = new List<string>() { Convert.ToString(reader["Telefone1"]), Convert.ToString(reader["Telefone2"]) },
                        Email = Convert.ToString(reader["Email"])

                    },
                    Endereco = new Endereco()
                    {
                        Logradouro = Convert.ToString(reader["Logradouro"]),
                        Bairro = Convert.ToString(reader["Bairro"]),
                        CEP = Convert.ToString(reader["CEP"]),
                        Cidade = Convert.ToString(reader["Cidade"]),
                        Complemento = Convert.ToString(reader["Complemento"]),
                        Estado = new Estado() { nome = Convert.ToString(reader["Estado"]), sigla = Convert.ToString(reader["UF"]) },
                        Numero = Convert.ToInt32(reader["Numero"])
                    },
                    CPF = Convert.ToString(reader["CPF"]),
                    RG = Convert.ToString(reader["RG"]),
                    CarteiraTrabalho = Convert.ToString(reader["Carteira"]),
                    Agencia = Convert.ToString(reader["Agencia"]),
                    Banco = Convert.ToString(reader["Banco"]),
                    Ativo = Convert.ToBoolean(reader["Ativo"]),
                    Conta_Corrente = Convert.ToString(reader["Conta"]),
                    Data_Admissao = Convert.ToDateTime(reader["DataAdmissao"]),
                    Data_Demissao = Convert.ToDateTime(reader["DataDemissao"]),
                    PIS = Convert.ToString(reader["PIS"]),
                    Salario = Convert.ToDouble(reader["Salario"]),
                    Cargo = Convert.ToString(reader["Cargo"]),
                    Usuario = Convert.ToString(reader["Usuario"]),
                    Senha = Convert.ToString(reader["Senha"])


                });

            }
            return listaResposta;


        }
    }
   
   
}